package threadpool;

import java.util.ArrayList;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class TestThreadPool {

    static ThreadFactory threadFactory = new MyThreadFactory("lujieni");
    static RejectedExecutionHandler rejectedExecutionHandler = new MyRejectPolicy();

    static  ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1), threadFactory, rejectedExecutionHandler);

    public static void main(String[] args) throws InterruptedException {

        System.out.println(3<<3);


        while (true){
            TimeUnit.SECONDS.sleep(1);
            new Thread(()->{
                ArrayList<Future<Integer>> futureList = new ArrayList<>();
                System.out.println(Thread.currentThread().getName());
                try {
                    for (int i = 0; i < 5 ; i++) {
                        int finalI = i;
                        Future<Integer> future = threadPoolExecutor.submit(() -> {
                            return finalI;
                        });
                        futureList.add(future);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                for (Future<Integer> future: futureList) {
                    try {
                        Integer i = future.get();
                        System.out.println("future.get() ="+i);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    } catch (ExecutionException e) {
                        throw new RuntimeException(e);
                    }
                }

            }).start();
        }
    }


    static class MyRejectPolicy implements RejectedExecutionHandler{


        /**
         * Method that may be invoked by a {@link ThreadPoolExecutor} when
         * {@link ThreadPoolExecutor#execute execute} cannot accept a
         * task.  This may occur when no more threads or queue slots are
         * available because their bounds would be exceeded, or upon
         * shutdown of the Executor.
         *
         * <p>In the absence of other alternatives, the method may throw
         * an unchecked {@link RejectedExecutionException}, which will be
         * propagated to the caller of {@code execute}.
         *
         * @param r        the runnable task requested to be executed
         * @param executor the executor attempting to execute this task
         * @throws RejectedExecutionException if there is no remedy
         */
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.out.println("线程池有任务被拒绝了请关注");
            System.out.println(Thread.currentThread().getName());
            throw new RuntimeException("线程池有任务被拒绝了请关注");
        }
    }

    static class MyThreadFactory implements ThreadFactory{

        private String namePrefix;

        private AtomicInteger count = new AtomicInteger(0);

        public MyThreadFactory(String namePrefix){
            this.namePrefix = namePrefix;
        }

        /**
         * Constructs a new {@code Thread}.  Implementations may also initialize
         * priority, name, daemon status, {@code ThreadGroup}, etc.
         *
         * @param r a runnable to be executed by new thread instance
         * @return constructed thread, or {@code null} if the request to
         * create a thread is rejected
         */
        @Override
        public Thread newThread(Runnable r) {
            String threadName = namePrefix + "-" + count.incrementAndGet();
            return new Thread(r, threadName);
        }
    }

}

